﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PMisuseAn.behaviour.model
{
    [Serializable()]
    public class StateMachine
    {
        private string machineName_;
        string clusterName_;    
        public List<Event> events;
        public List<State> states;
        public List<Transition> transitions;
        public State startState;
        public State endState;

        private State activeState_;
        private Transition activeTransition_;

        public StateMachine()
        {
            events = new List<Event>();
            states = new List<State>();
            transitions = new List<Transition>();
        }

        public void addEvent(Event event_)
        {
            events.Add(event_);
        }

        public void removeEvent(string eventName)
        {
            foreach (Event e in events)
            {
                if (e.name.Equals(eventName))
                {
                    events.Remove(e);
                    break;
                }
            }
        }

        public void updateEvent(Event eve)
        {
            removeEvent(eve.name);
            addEvent(eve);
        }

        public void addState(State state_)
        {
            states.Add(state_);
        }

        public void updateState(State state_)
        {
            removeState(state_.name);
            addState(state_);
        }

        public void removeState(string stateName)
        {
            foreach (State s in states)
            {
                if (s.name.Equals(stateName))
                {
                    states.Remove(s);
                    break;
                }
            }
        }

        public State getState(string stateName)
        {
            State s_ = null;
            foreach (State s in states)
            {
                if (s.name.Equals(stateName))
                {
                    s_ = s;
                    break;
                }
            }
            return s_;
        }

        public void addStateTransition(Transition transition)
        {
            transitions.Add(transition);
        }

        public void updateStateTransition(Transition trans)
        {
            removeStateTransition(trans.transitionName);
            addStateTransition(trans);
        }

        public void removeStateTransition(string stateTransition)
        {
            foreach (Transition s in transitions)
            {
                if (s.transitionName.Equals(stateTransition))
                {
                    transitions.Remove(s);
                    break;
                }
            }
        }
        public string machineName
        {
            get
            {
                return machineName_;
            }
            set
            {
                machineName_ = value;
            }
        }
        public string clusterName
        {
            get
            {
                return clusterName_;
            }
            set
            {
                clusterName_ = value;
            }
        }

        public State activeState
        {
            get
            {
                return activeState_;
            }
            set
            {
                activeState_ = value;
            }
        }

        public Transition activeTransition
        {
            get
            {
                return activeTransition_;
            }
            set
            {
                activeTransition_ = value;
            }
        }
        public void updateStateAction(Action action_)
        {
            foreach (State state in states)
            {
                if (state.name.Equals(action_.stateName))
                {
                    state.removeAction(action_.name);
                    state.addAction(action_);
                    break;
                }
            }

        }

        public void addStateAction(Action action)
        {
            foreach (State state in states)
            {
                if (state.name.Equals(action.stateName))
                {
                    state.addAction(action);
                    break;
                }
            }
        }
        public void removeStateAction(string stateName, string actionName)
        {
            foreach (State state in states)
            {
                if (state.name.Equals(stateName))
                {
                    foreach (PMisuseAn.behaviour.model.Action act in state.actions)
                    {
                        if (act.name.Equals(actionName))
                        {
                            state.removeAction(actionName);
                            break;
                        }
                    }
                    break;
                }
            }
        }

        public Transition getStateTransition(string transitionName,
            string startState, string endState, string associateEvent)
        {
            Transition transition = null;

            foreach (Transition trans in transitions)
            {
                if (trans.transitionName.Equals(transitionName) && trans.startState.Equals(startState)
                    && trans.endState.Equals(endState) && trans.associatedEevent.Equals(associateEvent))
                {
                    transition = trans;
                }
            }
            return transition;
        }

        public Action getStateAction(string actionName, string stateName)
        {
            PMisuseAn.behaviour.model.Action action = null;
            foreach (State st in states)
            {
                if (st.name.Equals(stateName))
                {
                    foreach (PMisuseAn.behaviour.model.Action act in st.actions)
                    {
                        if (act.name.Equals(actionName))
                        {
                            action = act;
                            break;
                        }
                    }
                    break;
                }
            }
            return action;
        }

        public State getStateX(string stateName)
        {
            State state = null;
            foreach (State st in states)
            {
                if (st.name.Equals(stateName))
                {
                    state = st;
                    break;
                }
            }
            return state;
        }
    }
}
